package com.listeningframework.boot.commons.httpclient;

import com.listeningframework.boot.commons.encrypt.EncodeUtils;
import com.listeningframework.boot.commons.http.HttpMethod;
import com.listeningframework.boot.commons.string.JacksonUtils;
import com.listeningframework.boot.constants.Encoding;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;

/**
 * HttpClient FactoryBean
 *
 * @author Listening
 * @version $Id: HttpClientFactoryBean.java, v 0.1 2016年8月6日 上午11:54:26 Listening Exp $
 */
public final class HttpClientFactory extends AbstractHttpClientFactory {

    private HttpClientFactory() {
        this(null);
    }

    private HttpClientFactory(HttpHost proxy) {
        super(proxy);
    }

    /**
     * 普通HttpClient实例
     *
     * @return HttpClientFactory
     */
    public static final HttpClientFactory newInstance() {
        return new HttpClientFactory();
    }

    /**
     * 普通带编码HttpClient实例
     *
     * @param encoding 编码方式
     * @return HttpClientFactory
     */
    public static final HttpClientFactory newInstance(Encoding encoding) {
        HttpClientFactory factory = newInstance();
        factory.setEncoding(encoding);
        return factory;
    }

    /**
     * 设置代理的HttpClient实例
     *
     * @param proxyIp   代理IP
     * @param proxyPort 代理端口
     * @return HttpClientFactory
     */
    public static final HttpClientFactory newInstance(String proxyIp, Integer proxyPort) {
        return new HttpClientFactory(new HttpHost(proxyIp, proxyPort));
    }

    /**
     * 设置代理和编码方式的HttpClient实例
     *
     * @param proxyIp   代理IP
     * @param proxyPort 代理端口
     * @param encoding  编码方式
     * @return HttpClientFactory
     */
    public static final HttpClientFactory newInstance(String proxyIp, Integer proxyPort, Encoding encoding) {
        HttpClientFactory factory = newInstance(proxyIp, proxyPort);
        factory.setEncoding(encoding);
        return factory;
    }

    /**
     * Get Address Content By HttpGet
     *
     * @param address 地址
     * @return String
     * @throws Exception 异常
     */
    public String getContent(String address) throws Exception {
        return EncodeUtils.getString(this.getBytes(address), encoding);
    }

    /**
     * Post方法查询
     *
     * @param address     请求地址
     * @param paramEntity 请求参数
     * @return String
     * @throws Exception 异常
     */
    public String postContent(String address, HttpEntity paramEntity) throws Exception {
        return EncodeUtils.getString(postBytes(address, paramEntity), encoding);
    }

    /**
     * HttpClient get方法请求返回Entity
     *
     * @param address 请求地址
     * @return byte[]
     * @throws Exception 异常
     */
    public byte[] getBytes(String address) throws Exception {
        HttpClinetMethodBuilder builder = HttpClinetMethodBuilder.newinstance();
        builder.withAddress(address);
        builder.withHttpMethod(HttpMethod.GET);
        HttpClientMethod clientMethod = builder.build();
        return getHttpClientBytes(clientMethod);
    }

    /**
     * Post Entity
     * '
     *
     * @param address    请求地址
     * @param httpEntity 请求参数对象
     * @return byte[]
     * @throws Exception post执行异常
     */
    public byte[] postBytes(String address, HttpEntity httpEntity) throws Exception {
        HttpClinetMethodBuilder builder = HttpClinetMethodBuilder.newinstance();
        builder.withAddress(address);
        builder.withHttpMethod(HttpMethod.POST);
        builder.withHttpEntity(httpEntity);
        HttpClientMethod clientMethod = builder.build();
        return getHttpClientBytes(clientMethod);
    }

    /**
     * execute
     *
     * @param clientMethod 请求方式
     * @return byte[]
     * @throws Exception 异常
     */
    public byte[] executeBytes(HttpClientMethod clientMethod) throws Exception {
        return getHttpClientBytes(clientMethod);
    }

    /**
     * Execute
     *
     * @param clientMethod 请求方式
     * @return String
     * @throws Exception 异常
     */
    public String executeContent(HttpClientMethod clientMethod) throws Exception {
        return EncodeUtils.getString(getHttpClientBytes(clientMethod), clientMethod.getEncoding());
    }

    public void traceCookie() {
        System.err.println("[Cookie]==========>" + JacksonUtils.toJson(getCookieStore().getCookies()));
    }
}
